package Charts;

/**
 * User: Mike
 * Date: 11/12/11
 */


import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.AbstractRenderer;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.Minute;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;


public class ChartScatter extends ApplicationFrame {

    private JFreeChart chart;

    private TimeSeriesCollection datasetL1;
    private TimeSeriesCollection datasetL2;
    private TimeSeriesCollection datasetL3;
    private TimeSeriesCollection datasetL4;
    private TimeSeriesCollection datasetR1;
    private TimeSeriesCollection datasetR2;
    private TimeSeriesCollection datasetR3;
    private TimeSeriesCollection datasetR4;

    private String chartTitle = "Column Temperature  & abv";
    private String chartXaxis = "Date";
    private String chartYaxisNameL = "Column Temperature [C]";
    private String chartYaxisNameR = "Corrected Vapor abv [%]";


    public ChartScatter(final String title, String chartTitle, String chartXaxis, String chartYaxisL, String chartYaxisR) {
        super(title);
        this.chartTitle = chartTitle;
        this.chartXaxis = chartXaxis;
        this.chartYaxisNameL = chartYaxisL;
        this.chartYaxisNameR = chartYaxisR;
    }

    public ChartScatter(final String title) {
        super(title);
        chart = ChartFactory.createTimeSeriesChart(chartTitle, chartXaxis, chartYaxisNameL, datasetL1, true, true, false);
    }


    private void CreateScatterChart() {
        chart = ChartFactory.createTimeSeriesChart(chartTitle, chartXaxis, chartYaxisNameL, datasetL1, true, true, false);
        final XYPlot plot = chart.getXYPlot();
        chart.setBackgroundPaint(Color.white);
        chart.setBorderPaint(Color.white);
        final NumberAxis axis2 = new NumberAxis(chartYaxisNameR);
        axis2.setAutoRangeIncludesZero(false);
        plot.setRangeAxis(1, axis2);
        plot.setBackgroundPaint(Color.white);
        plot.setDataset(1, datasetR1);
        plot.mapDatasetToRangeAxis(1, 1);

        final XYItemRenderer renderer = plot.getRenderer();
        renderer.setToolTipGenerator(StandardXYToolTipGenerator.getTimeSeriesInstance());

        renderer.setSeriesPaint(0, Color.blue);

        if (renderer instanceof StandardXYItemRenderer) {
            final StandardXYItemRenderer rr = (StandardXYItemRenderer) renderer;
            rr.setShapesFilled(true);
            rr.setBaseShapesVisible(true);
        }

        final StandardXYItemRenderer render1 = new StandardXYItemRenderer();
        render1.setSeriesPaint(0, Color.blue);
        render1.setShapesFilled(true);
        render1.setBaseShapesVisible(true);
        render1.setToolTipGenerator(StandardXYToolTipGenerator.getTimeSeriesInstance());
        plot.setRenderer(0, render1);
        final StandardXYItemRenderer render2 = new StandardXYItemRenderer();
        render2.setSeriesPaint(0, Color.black);
        render2.setShapesFilled(true);
        render2.setBaseShapesVisible(true);
        render2.setToolTipGenerator(StandardXYToolTipGenerator.getTimeSeriesInstance());
        plot.setRenderer(1, render2);
        final DateAxis axis = (DateAxis) plot.getDomainAxis();
//        axis.setDateFormatOverride(new SimpleDateFormat("DD-MMM-yyyy"));
        axis.setDateFormatOverride(new SimpleDateFormat("hh:mm a EEE, MMM d"));
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500, 270));
        setContentPane(chartPanel);
    }


    private void CreateChartTime2() {
        chart = ChartFactory.createTimeSeriesChart(chartTitle, chartXaxis, chartYaxisNameL, datasetL1, true, true, false);

        final XYPlot plot = chart.getXYPlot();
        plot.getRangeAxis().setAutoRangeMinimumSize(17.);


        plot.getRangeAxis().setAutoRange(true);


        chart.setBackgroundPaint(Color.white);
        chart.setBorderPaint(Color.white);
        plot.setDataset(2, datasetL2);

        final NumberAxis axis2 = new NumberAxis(chartYaxisNameR);
        axis2.setAutoRangeIncludesZero(false);
        plot.setRangeAxis(1, axis2);
        plot.setBackgroundPaint(Color.white);
        plot.setDataset(1, datasetR1);
        plot.mapDatasetToRangeAxis(1, 1);

        final XYItemRenderer renderer = plot.getRenderer();

        plot.setRenderer(0, renderData(renderer, Color.blue, false));
        plot.setRenderer(1, renderData(renderer, Color.black, false));
        plot.setRenderer(2, renderData(renderer, Color.green, true));

        final DateAxis axis = (DateAxis) plot.getDomainAxis();
//        axis.setDateFormatOverride(new SimpleDateFormat("DD-MMM-yyyy"));
        axis.setDateFormatOverride(new SimpleDateFormat("hh:mm a EEE, MMM d"));
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500, 270));
        setContentPane(chartPanel);
    }

    private void CreateChartTimeL1R2() {
        chart = ChartFactory.createTimeSeriesChart(chartTitle, chartXaxis, chartYaxisNameL, datasetL1, true, true, false);

        final XYPlot plot = chart.getXYPlot();
        plot.getRangeAxis().setAutoRangeMinimumSize(17.);
        plot.getRangeAxis().setAutoRange(true);
        chart.setBackgroundPaint(Color.white);
        chart.setBorderPaint(Color.white);
        final NumberAxis axis2 = new NumberAxis(chartYaxisNameR);
        axis2.setAutoRangeIncludesZero(false);
        plot.setRangeAxis(1, axis2);
        plot.setBackgroundPaint(Color.white);

        plot.setDataset(0, datasetL1);
        plot.setDataset(1, datasetR1);
        plot.setDataset(2, datasetR2);

        plot.mapDatasetToRangeAxis(1, 1);
        plot.mapDatasetToRangeAxis(2, 1);

        final XYItemRenderer renderer = plot.getRenderer();

        plot.setRenderer(0, renderData(renderer, Color.blue, false));
        plot.setRenderer(1, renderData(renderer, Color.black, false));
        plot.setRenderer(2, renderData(renderer, Color.green, true));
//        plot.setRenderer(2, renderData(renderer, Color.darkGray, true));

        final DateAxis axis = (DateAxis) plot.getDomainAxis();
//        axis.setDateFormatOverride(new SimpleDateFormat("DD-MMM-yyyy"));
        axis.setDateFormatOverride(new SimpleDateFormat("hh:mm a EEE, MMM d"));
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500, 270));
        setContentPane(chartPanel);
    }

    private StandardXYItemRenderer renderData(XYItemRenderer renderer, Color color, boolean setBaseStroke) {
        final StandardXYItemRenderer render = new StandardXYItemRenderer();
        ((AbstractRenderer) renderer).setAutoPopulateSeriesStroke(false);

        if (setBaseStroke)
            render.setBaseStroke(new BasicStroke(5));
        if (setBaseStroke)
            renderer.setSeriesStroke(2, new BasicStroke(5));

        render.setSeriesPaint(0, color);
        render.setShapesFilled(true);
        render.setBaseShapesVisible(true);
        render.setToolTipGenerator(StandardXYToolTipGenerator.getTimeSeriesInstance());

        return render;
    }

    public void updateChart(List xAxisData, List leftAxisData, List rightAxisData, String leftAxisTitle,String rightAxisTitle) {
        datasetL1 = createDataset(xAxisData, leftAxisData, leftAxisTitle);
//        datasetL1 = createDataset(xAxisData, leftAxisData, "Column Temp");
        datasetR1 = createDataset(xAxisData, rightAxisData, rightAxisTitle);
//        datasetR1 = createDataset(xAxisData, rightAxisData, "Vapor abv asdfsd");
        CreateScatterChart();
    }

    public void updateChart(ArrayList<Double> milliT, ArrayList<Double> columnC, ArrayList<Double> abv, ArrayList<Double> kalman) {
        datasetL1 = createDataset(milliT, columnC, "Column Temp");
        datasetL2 = createDataset(milliT, kalman, "Column Temp KF");
        datasetR1 = createDataset(milliT, abv, "Vapor abv");
        CreateChartTime2();
    }

    public void updateChartL1R2(ArrayList<Double> milliT, ArrayList<Double> columnC, ArrayList<Double> abv, ArrayList<Double> milliT2, ArrayList<Double> abv2) {
        datasetL1 = createDataset(milliT, columnC, "Column Temp");
        datasetR1 = createDataset(milliT, abv, "Vapor abv");
        datasetR2 = createDataset(milliT2, abv2, "Distillate abv");
        CreateChartTimeL1R2();
    }

    private TimeSeriesCollection createDataset(List<Double> milliT, List<Double> Value, String name) {
        TimeSeries s1 = new TimeSeries(name, Second.class);
        for (int i = 0; i < milliT.size(); i++) {
            Double dtemp = milliT.get(i);
            Long longs = dtemp.longValue();
            s1.addOrUpdate(new Second(new Date(longs)), Value.get(i));
        }
        TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(s1);
        return dataset;
    }

    private XYDataset createDataset1() {
        final TimeSeries s1 = new TimeSeries("Random Data 1", Minute.class);
        s1.add(new Minute(1, 1, 1, 2, 2001), 181.8);
        s1.add(new Minute(3, 1, 1, 2, 2001), 167.3);
        s1.add(new Minute(4, 1, 1, 2, 2001), 153.8);
        s1.add(new Minute(5, 1, 1, 2, 2001), 167.6);
        s1.add(new Minute(6, 1, 1, 2, 2001), 158.8);
        s1.add(new Minute(7, 1, 1, 2, 2001), 148.3);
        s1.add(new Minute(8, 1, 1, 2, 2001), 153.9);
        s1.add(new Minute(9, 1, 1, 2, 2001), 142.7);
        s1.add(new Minute(10, 1, 1, 2, 2001), 123.2);
        s1.add(new Minute(11, 1, 1, 2, 2001), 131.8);
        s1.add(new Minute(12, 1, 1, 2, 2001), 139.6);
        final TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(s1);
        return dataset;
    }


    public XYDataset createDataset2() {
        final TimeSeries s2 = new TimeSeries("Random Data 2", Minute.class);
//        final TimeSeries s1 = new TimeSeries("Random Data 2", Millisecond.class);
        s2.add(new Minute(2, 1, 1, 2, 2001), 429.6);
        s2.add(new Minute(3, 1, 1, 2, 2001), 323.2);
        s2.add(new Minute(4, 1, 1, 2, 2001), 417.2);
        s2.add(new Minute(5, 1, 1, 2, 2001), 624.1);
        s2.add(new Minute(6, 1, 1, 2, 2001), 422.6);
        s2.add(new Minute(7, 1, 1, 2, 2001), 619.2);
        s2.add(new Minute(8, 1, 1, 2, 2001), 416.5);
        s2.add(new Minute(9, 1, 1, 2, 2001), 512.7);
        s2.add(new Minute(10, 1, 1, 2, 2001), 501.5);
        s2.add(new Minute(11, 1, 1, 2, 2001), 306.1);
        s2.add(new Minute(12, 1, 1, 2, 2001), 410.3);
        final TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(s2);
        return dataset;
    }

    // creates a sized & centered chart, you only the the last line in here to to display & update the display of a chart
    public void displayChart(ChartScatter chartScatter){
        chartScatter.pack();
        RefineryUtilities.centerFrameOnScreen(chartScatter);
        chartScatter.setVisible(true);
    }

    public static void main(final String[] args) {
        final ChartScatter demo = new ChartScatter("Dual Axis Demo 2");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
     }

    public JFreeChart getChart() {
        return chart;
    }

    public void setChartTitle(String chartTitle) {
        this.chartTitle = chartTitle;
    }

    public void setChartXaxis(String chartXaxis) {
        this.chartXaxis = chartXaxis;
    }

    public void setChartYaxisNameL(String chartYaxisNameL) {
        this.chartYaxisNameL = chartYaxisNameL;
    }

    public void setChartYaxisNameR(String chartYaxisNameR) {
        this.chartYaxisNameR = chartYaxisNameR;
    }

}